package com.qingcheng.service.impl;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.qingcheng.dao.OrderConfigMapper;
import com.qingcheng.dao.OrderItemMapper;
import com.qingcheng.dao.OrderLogMapper;
import com.qingcheng.dao.OrderMapper;
import com.qingcheng.entity.PageResult;
import com.qingcheng.pojo.order.*;
import com.qingcheng.service.goods.CategoryService;
import com.qingcheng.service.goods.SkuService;
import com.qingcheng.service.goods.StockBackService;
import com.qingcheng.service.order.CartService;
import com.qingcheng.service.order.OrderService;
import com.qingcheng.service.order.WeixinPayService;
import com.qingcheng.util.IdWorker;
import org.aspectj.weaver.ast.Or;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import sun.tools.tree.OrExpression;
import tk.mybatis.mapper.entity.Example;

import java.net.SocketTimeoutException;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Service(interfaceClass = OrderService.class)
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    /**
     * 返回全部记录
     * @return
     */
    public List<Order> findAll() {
        return orderMapper.selectAll();
    }

    /**
     * 分页查询
     * @param page 页码
     * @param size 每页记录数
     * @return 分页结果
     */
    public PageResult<Order> findPage(int page, int size) {
        PageHelper.startPage(page,size);
        Page<Order> orders = (Page<Order>) orderMapper.selectAll();
        return new PageResult<Order>(orders.getTotal(),orders.getResult());
    }

    /**
     * 条件查询
     * @param searchMap 查询条件
     * @return
     */
    public List<Order> findList(Map<String, Object> searchMap) {
        Example example = createExample(searchMap);
        return orderMapper.selectByExample(example);
    }

    /**
     * 分页+条件查询
     * @param searchMap
     * @param page
     * @param size
     * @return
     */
    public PageResult<Order> findPage(Map<String, Object> searchMap, int page, int size) {
        PageHelper.startPage(page,size);
        Example example = createExample(searchMap);
        Page<Order> orders = (Page<Order>) orderMapper.selectByExample(example);
        return new PageResult<Order>(orders.getTotal(),orders.getResult());
    }

    /**
     * 根据Id查询
     * @param id
     * @return
     */
    public Order findById(String id) {
        return orderMapper.selectByPrimaryKey(id);
    }


    @Autowired
    private CartService cartService;

    @Reference
    private SkuService skuService;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 新增(修改)
     * @param order
     */
    @Transactional
    public Map<String,Object> add(Order order) {

        //查找选中的订单(刷新订单)
        List<Map<String, Object>> cartList = cartService.findNewOrderItemList(order.getUsername());
        List<OrderItem> orderItemList = cartList.stream()
                .filter(cart -> (boolean) cart.get("checked") == true)
                .map(cart -> (OrderItem) cart.get("item"))
                .collect(Collectors.toList());

        //扣减库存
        if(!skuService.deductionStock(orderItemList)){
            throw  new RuntimeException("库存不足");
        }

        try {
            //保存订单主表 order,里面的部分内容为前端的，并不全，要后端补齐
            order.setId(idWorker.nextId()+"");//id

            IntStream numStream = orderItemList.stream().mapToInt(OrderItem::getNum);
            IntStream moneyStream = orderItemList.stream().mapToInt(OrderItem::getMoney);//没有优惠前的金额
            int totalNum = numStream.sum();
            int totalMoney = moneyStream.sum();
            int preMoney = cartService.preferentialMoney(order.getUsername());

            order.setTotalNum(totalNum);//总数量
            order.setTotalMoney(totalMoney);//订单总金额
            order.setPreMoney(preMoney);//优惠金额
            order.setPayMoney(totalMoney-preMoney);//优惠后的金额，即应付的金额
            order.setCreateTime(new Date());//订单创建时间
            order.setOrderStatus("0");//订单状态
            order.setPayStatus("0");//支付状态
            order.setConsignStatus("0");//发货状态

            orderMapper.insert(order);


            //保存订单明细表
            //支付比例
//            System.out.println(("order.getmoney"+order.getPayMoney()));
//            System.out.println(("totalMoney:"+totalMoney));
            double proportion = (double)order.getPayMoney()/totalMoney;
            for(OrderItem orderItem:orderItemList){

                orderItem.setId(idWorker.nextId()+"");
                orderItem.setOrderId(order.getId());
                orderItem.setPayMoney((int)(orderItem.getMoney()*proportion));//每个订单的支付金额

                orderItemMapper.insert(orderItem);
            }

            //发送延时消息，看是否支付成功
            rabbitTemplate.convertAndSend("","queue.ordercreate",order.getId());
        } catch (Exception e) {
            rabbitTemplate.convertAndSend("","queue.skuback", JSON.toJSONString(orderItemList));
            throw new RuntimeException("创建订单失败");//抛出异常，让其回滚！

        }

        //清除购物车
        cartService.deleteCheckedCart(order.getUsername());

        Map map = new HashMap();
        map.put("ordersn",order.getId());
        map.put("money",order.getPayMoney());

        return map;
    }

    /**
     * 修改
     * @param order
     */
    public void update(Order order) {
        orderMapper.updateByPrimaryKeySelective(order);
    }

    /**
     *  删除
     * @param id
     */
    public void delete(String id) {
        orderMapper.deleteByPrimaryKey(id);
    }

    /**
     * 构建查询条件
     * @param searchMap
     * @return
     */
    private Example createExample(Map<String, Object> searchMap){
        Example example=new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        if(searchMap!=null){
            // 订单id
            if(searchMap.get("id")!=null && !"".equals(searchMap.get("id"))){
                criteria.andLike("id","%"+searchMap.get("id")+"%");
            }
            // 支付类型，1、在线支付、0 货到付款
            if(searchMap.get("payType")!=null && !"".equals(searchMap.get("payType"))){
                criteria.andLike("payType","%"+searchMap.get("payType")+"%");
            }
            // 物流名称
            if(searchMap.get("shippingName")!=null && !"".equals(searchMap.get("shippingName"))){
                criteria.andLike("shippingName","%"+searchMap.get("shippingName")+"%");
            }
            // 物流单号
            if(searchMap.get("shippingCode")!=null && !"".equals(searchMap.get("shippingCode"))){
                criteria.andLike("shippingCode","%"+searchMap.get("shippingCode")+"%");
            }
            // 用户名称
            if(searchMap.get("username")!=null && !"".equals(searchMap.get("username"))){
                criteria.andLike("username","%"+searchMap.get("username")+"%");
            }
            // 买家留言
            if(searchMap.get("buyerMessage")!=null && !"".equals(searchMap.get("buyerMessage"))){
                criteria.andLike("buyerMessage","%"+searchMap.get("buyerMessage")+"%");
            }
            // 是否评价
            if(searchMap.get("buyerRate")!=null && !"".equals(searchMap.get("buyerRate"))){
                criteria.andLike("buyerRate","%"+searchMap.get("buyerRate")+"%");
            }
            // 收货人
            if(searchMap.get("receiverContact")!=null && !"".equals(searchMap.get("receiverContact"))){
                criteria.andLike("receiverContact","%"+searchMap.get("receiverContact")+"%");
            }
            // 收货人手机
            if(searchMap.get("receiverMobile")!=null && !"".equals(searchMap.get("receiverMobile"))){
                criteria.andLike("receiverMobile","%"+searchMap.get("receiverMobile")+"%");
            }
            // 收货人地址
            if(searchMap.get("receiverAddress")!=null && !"".equals(searchMap.get("receiverAddress"))){
                criteria.andLike("receiverAddress","%"+searchMap.get("receiverAddress")+"%");
            }
            // 订单来源：1:web，2：app，3：微信公众号，4：微信小程序  5 H5手机页面
            if(searchMap.get("sourceType")!=null && !"".equals(searchMap.get("sourceType"))){
                criteria.andLike("sourceType","%"+searchMap.get("sourceType")+"%");
            }
            // 交易流水号
            if(searchMap.get("transactionId")!=null && !"".equals(searchMap.get("transactionId"))){
                criteria.andLike("transactionId","%"+searchMap.get("transactionId")+"%");
            }
            // 订单状态
            if(searchMap.get("orderStatus")!=null && !"".equals(searchMap.get("orderStatus"))){
                criteria.andLike("orderStatus","%"+searchMap.get("orderStatus")+"%");
            }
            // 支付状态
            if(searchMap.get("payStatus")!=null && !"".equals(searchMap.get("payStatus"))){
                criteria.andLike("payStatus","%"+searchMap.get("payStatus")+"%");
            }
            // 发货状态
            if(searchMap.get("consignStatus")!=null && !"".equals(searchMap.get("consignStatus"))){
                criteria.andLike("consignStatus","%"+searchMap.get("consignStatus")+"%");
            }
            // 是否删除
            if(searchMap.get("isDelete")!=null && !"".equals(searchMap.get("isDelete"))){
                criteria.andLike("isDelete","%"+searchMap.get("isDelete")+"%");
            }

            // 数量合计
            if(searchMap.get("totalNum")!=null ){
                criteria.andEqualTo("totalNum",searchMap.get("totalNum"));
            }
            // 金额合计
            if(searchMap.get("totalMoney")!=null ){
                criteria.andEqualTo("totalMoney",searchMap.get("totalMoney"));
            }
            // 优惠金额
            if(searchMap.get("preMoney")!=null ){
                criteria.andEqualTo("preMoney",searchMap.get("preMoney"));
            }
            // 邮费
            if(searchMap.get("postFee")!=null ){
                criteria.andEqualTo("postFee",searchMap.get("postFee"));
            }
            // 实付金额
            if(searchMap.get("payMoney")!=null ){
                criteria.andEqualTo("payMoney",searchMap.get("payMoney"));
            }

        }
        return example;
    }

    /////////////////////////////////////////////////////////////////////////////


    @Autowired
    private OrderLogMapper orderLogMapper;

    @Autowired
    private OrderConfigMapper orderConfigMapper;

    /**
     * 根据ID查询订单
     * @param id
     * @return
     */
    public OrderCombination findOrderCombinationById(String id){

        System.out.println("收到");

        //查询订单主表
        Order order = orderMapper.selectByPrimaryKey(id);

        System.out.println("id:"+order.getId());
        System.out.println("name:"+order.getShippingName());

        //查询订单详情列表
        Example example = new Example(OrderItem.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderId",id);
        List<OrderItem> orderItems = orderItemMapper.selectByExample(example);

        System.out.println("name"+orderItems.get(0).getName());

        //封装，返回
        OrderCombination orderCombination = new OrderCombination();
        orderCombination.setOrder(order);
        orderCombination.setOrderItems(orderItems);

        return orderCombination;
    }

    /**
     * 查找所有未发货的订单
     * @param ids
     * @return
     */
    public List<Order> findNotSendOrderList(String[] ids){

        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderStatus","1");//用户虽然勾选了非代发货的，直接刷选出去
//        criteria.andEqualTo("consignStatus","0");//发货状态为0，表示未发货，后者可以称为揽货，是否真的在运送，真实有快递员送
        if(ids!=null){
            criteria.andIn("id", Arrays.asList(ids));
            System.out.println("有");
        }else{
            System.out.println("没有");
            return null;
        }
        List<Order> orders= orderMapper.selectByExample(example);
        return orders;
    }

    /**
     * 批量发货
     *
     * @param orders
     */
    @Override
    public void batchSend(List<Order> orders) {
        for(Order order: orders){
            if((order.getShippingName()==null||order.getShippingName().equals(""))
                    &&(order.getShippingCode()==null||order.getShippingCode().equals(""))){
                throw new RuntimeException("请填写配置方式和物流单号");
            }
        }

        for(Order order:orders){
            Date date = new Date();
            order.setOrderStatus("3");//订单状态 已发货
//            order.setConsignStatus("1");//发货状态 已发货，这个必须有快递员来真实拉货才显示发货，个人认为
            order.setConsignTime(date);//发货时间
            orderMapper.updateByPrimaryKeySelective(order);

            //记录订单日志
            OrderLog orderLog = new OrderLog();
            orderLog.setId(idWorker.nextId()+"");
            orderLog.setOperater("Admin");
            orderLog.setOperateTime(date);
            orderLog.setOrderId(order.getId());
            orderLog.setOrderStatus("3");
            orderLog.setPayStatus(order.getPayStatus());
            orderLog.setConsignStatus(order.getConsignStatus());
            orderLog.setRemarks("订单已发货");

            orderLogMapper.insert(orderLog);
        }
    }



    /**
     * 订单超时处理逻辑
     */
    public void orderTimeOutLogic(){
        //订单超时未付款 自动关闭

        //查询超时时间
        OrderConfig orderConfig = orderConfigMapper.selectByPrimaryKey(1);
        Integer orderTimeout = orderConfig.getOrderTimeout();//超时时间 (分) 60
        LocalDateTime localDateTime = LocalDateTime.now().minusMinutes(orderTimeout); //得到此时超时的时间点

        //设置查询条件
        Example example = new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andLessThanOrEqualTo("createTime",localDateTime);//创建时间小于等于超时时间
        criteria.andEqualTo("orderStatus","0");//订单状态为未付款
        criteria.andEqualTo("isDelete","0");//订单未删除

        //查询超时时间
        List<Order> orders = orderMapper.selectByExample(example);
        for(Order order:orders){

            Date date = new Date();

            //更改订单状态
            order.setOrderStatus("4");
            order.setCloseTime(date);//关闭日期
            orderMapper.updateByPrimaryKeySelective(order);

            //记录订单变动日志
            OrderLog orderLog = new OrderLog();
            orderLog.setId(idWorker.nextId()+"");
            orderLog.setOperater("system");//系统
            orderLog.setOperateTime(date);//当前日期
            orderLog.setOrderId(order.getId());//订单ID
            orderLog.setOrderStatus("4");//订单关闭
            orderLog.setPayStatus(order.getPayStatus());//付款状态
            orderLog.setConsignStatus(order.getConsignStatus());//发货状态
            orderLog.setRemarks("订单超时,系统自动关闭");//备注

        }
    }


    /**
     * 合并订单
     * @param masterId 主订单ID
     * @param branchId 从订单ID
     */
    public void mergeOrder(String masterId,String branchId){

        //获取主从订单
        Order masterOrder = orderMapper.selectByPrimaryKey(masterId);
        Order branchOrder = orderMapper.selectByPrimaryKey(branchId);

        //将“从订单”的金额等信息合并到“主订单”
        masterOrder.setTotalNum(masterOrder.getTotalNum()+branchOrder.getTotalNum());
        masterOrder.setTotalMoney(masterOrder.getTotalMoney()+branchOrder.getTotalMoney());
        masterOrder.setPreMoney(masterOrder.getPreMoney()+branchOrder.getPreMoney());
        masterOrder.setPostFee(masterOrder.getPostFee()+branchOrder.getPostFee());
        masterOrder.setPayMoney(masterOrder.getPayMoney()+branchOrder.getPayMoney());
        orderMapper.updateByPrimaryKeySelective(masterOrder);

        //“从订单”的订单明细也 归属于主订单
        Example example = new Example(OrderItem.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderId",branchId);
        List<OrderItem> branchOrderItems = orderItemMapper.selectByExample(example);
        for(OrderItem orderItem:branchOrderItems){
            orderItem.setOrderId(masterId);
            orderItemMapper.updateByPrimaryKeySelective(orderItem);
        }

        //对“从订单”添加删除标记（逻辑删除）
        branchOrder.setIsDelete("1");

        //记录订单日志
        Date date = new Date();

        OrderLog orderLog = new OrderLog();
        orderLog.setId(idWorker.nextId()+"");
        orderLog.setOperater("Admin");
        orderLog.setOperateTime(date);
        orderLog.setOrderId(masterId);
        orderLog.setOrderStatus(masterOrder.getOrderStatus());
        orderLog.setPayStatus(masterOrder.getPayStatus());
        orderLog.setConsignStatus(masterOrder.getConsignStatus());
        orderLog.setRemarks("将订单和"+branchId+"订单合并");
        orderLogMapper.insert(orderLog);

        orderLog.setId(idWorker.nextId()+"");
        orderLog.setOperater("Admin");
        orderLog.setOperateTime(date);
        orderLog.setOrderId(branchId);
        orderLog.setOrderStatus(branchOrder.getOrderStatus());
        orderLog.setPayStatus(branchOrder.getPayStatus());
        orderLog.setConsignStatus(masterOrder.getConsignStatus());
        orderLog.setRemarks("将订单和"+masterId+"订单合并,此订单已经删除");
        orderLogMapper.insert(orderLog);
    }

    /**
     * 拆分订单
     * @param orderItems
     */
    public void splitOrder(List<OrderItem> orderItems){

        for(OrderItem orderItem:orderItems){
            //旧订单明细
            OrderItem orderItem1 = orderItemMapper.selectByPrimaryKey(orderItem.getId());
            if(orderItem.getNum()>orderItem1.getNum()){
                throw new RuntimeException("订单拆分数量不合理");
            }
            //创建新订单明细
            OrderItem orderItem2 = new OrderItem();
            orderItem2.setId(idWorker.nextId()+"");
            orderItem2.setCategoryId1(orderItem1.getCategoryId1());
            orderItem2.setCategoryId2(orderItem1.getCategoryId2());
            orderItem2.setCategoryId3(orderItem1.getCategoryId3());
            orderItem2.setSpuId(orderItem1.getSpuId());
            orderItem2.setSkuId(orderItem1.getSkuId());
            orderItem2.setOrderId(orderItem1.getOrderId());
            orderItem2.setName(orderItem1.getName());
            orderItem2.setPrice(orderItem1.getPrice());
            orderItem2.setNum(orderItem.getNum());
            orderItem2.setMoney(orderItem1.getPrice()*orderItem.getNum());
            orderItem2.setPayMoney(orderItem1.getPrice()/orderItem1.getNum()*orderItem.getNum());
            orderItem2.setImage(orderItem1.getImage());
            orderItem2.setWeight(orderItem1.getWeight()/orderItem1.getNum()*orderItem.getNum());
            orderItem2.setPostFee(orderItem1.getPostFee()/orderItem1.getNum()*orderItem.getNum());
            orderItem2.setIsReturn("0");

            //插入一个新订单
            orderItemMapper.insert(orderItem2);

            orderItem1.setNum(orderItem1.getNum()-orderItem2.getNum());
            orderItem1.setMoney(orderItem1.getMoney()-orderItem2.getMoney());
            orderItem1.setPayMoney(orderItem1.getPayMoney()-orderItem2.getPayMoney());
            orderItem1.setWeight(orderItem1.getWeight()-orderItem2.getWeight());
            orderItem1.setPostFee(orderItem1.getPostFee()-orderItem2.getPostFee());

            //更新旧订单
            orderItemMapper.updateByPrimaryKeySelective(orderItem1);

        }

    }

    /**
     * 修改订单状态
     * @param orderId
     * @param transactionId
     */
    public void updatePayStatus(String orderId,String transactionId){

        //修改订单状态
        Order order = orderMapper.selectByPrimaryKey(orderId);
        //存在订单且状态为0
        if(order!=null && "0".equals(order.getOrderStatus())){

            order.setPayStatus("1");
            order.setOrderStatus("1");
            Date date = new Date();
            order.setUpdateTime(date);
            order.setPayTime(date);
            order.setTransactionId(transactionId);//微信返回的交易流水号
            orderMapper.updateByPrimaryKeySelective(order);

            //记录订单日志
            OrderLog orderLog = new OrderLog();
            orderLog.setId(idWorker.nextId()+"");
            orderLog.setOperater("system");//系统
            orderLog.setOperateTime(date);
            orderLog.setOrderStatus("1");
            orderLog.setPayStatus("1");
            orderLog.setRemarks("交易流水号："+transactionId);
            orderLog.setOrderId(orderId);
            orderLogMapper.insert(orderLog);


        }

    }

    @Autowired
    private WeixinPayService weixinPayService;

    @Reference
    private StockBackService stockBackService;
    /**
     * 关闭订单
     * @param orderId
     */
    public void closeOrder(String orderId){

        //1.调用微信关闭接口，关闭订单
        Map<String, String> mapResult = weixinPayService.closeOrder(orderId);

        if(mapResult==null){
            throw new RuntimeException("关闭失败");
        }else {
            if("SUCCESS".equals(mapResult.get("return_code"))){
                if("SUCCESS".equals(mapResult.get("result_code"))){ //查询交易状态是否为SUCCESS
//                    System.out.println("关闭成功");
                }
            }else{
                throw new RuntimeException(mapResult.get("err_code_des"));//返回错误描述
            }
        }

        //2.修改订单表的订单状态
        Order order = orderMapper.selectByPrimaryKey(orderId);
        if(order!=null && (!"4".equals(order.getOrderStatus())) ){
            order.setOrderStatus("4");//订单超时关闭
            orderMapper.updateByPrimaryKey(order);
        }

        //3.记录订单日志
        OrderLog orderLog = new OrderLog();
        orderLog.setId(idWorker.nextId()+"");
        orderLog.setOperater("system");//系统
        orderLog.setOperateTime(new Date());
        orderLog.setOrderStatus("4");
        orderLog.setPayStatus("0");
        orderLog.setRemarks("订单超时关闭");
        orderLog.setOrderId(orderId);
        orderLogMapper.insert(orderLog);

        //4.恢复商品表库存 添加列表到库存回滚表
        Example example = new Example(OrderItem.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("orderId",orderId);
        List<OrderItem> orderItemList = orderItemMapper.selectByExample(example);
        stockBackService.addList(orderItemList);

    }

    /**
     * 订单补偿操作(本地查询订单为未支付，微信查询已支付，以微信为准)
     * @param orderId
     */
    public void updateOrderForCompensate(String orderId){
        //修改订单表的订单状态
        Order order = orderMapper.selectByPrimaryKey(orderId);
        order.setPayStatus("1");//设置为支付
        orderMapper.updateByPrimaryKey(order);

        //记录订单日志
        OrderLog orderLog = new OrderLog();
        orderLog.setId(idWorker.nextId()+"");
        orderLog.setOperater("system");//系统
        orderLog.setOperateTime(new Date());
        orderLog.setOrderStatus("1");//待发货
        orderLog.setPayStatus("1");//已付款
        orderLog.setRemarks("微信显示已经支付，故此修改");
        orderLog.setOrderId(orderId);
        orderLogMapper.insert(orderLog);
    }


}
